import  pygame
from gameworld import GW
import time
import random
from blocktype import BlockType
from game_event_manager import GameEventManager

class Block:
    def __init__(self, x, y):
        self.bx = x
        self.by = y
        self.image_dict = {}
        self.load_images()

        self.color = None
        self.data = None
        self.type_name = ''
        self.image = None

        self.random_data()

        self.inter = 20
        self.tick = self.inter

        self.board = None
        self.visible = True
        self.enable = True


        GameEventManager.register_handler("GAME_OVER", self.on_game_over)
        GameEventManager.register_handler("GAME_PAUSE", self.on_game_pause)
        GameEventManager.register_handler("GAME_RESUME", self.on_game_resume)

    def update(self, key_pressed):

        if not self.enable:
            return

        self.tick -= 1
        if self.tick <= 0:
            self.tick = self.inter
            self.by += 1

        if key_pressed[pygame.K_LEFT]:
            self.bx -= 1
            self.check_left()  # 如果左边有障碍，则回退
            time.sleep(0.1)
        if key_pressed[pygame.K_RIGHT]:
            self.bx += 1
            self.check_right()  # 如果右边有障碍，则回退
            time.sleep(0.1)
        if key_pressed[pygame.K_DOWN]:
            self.by += 1
            if self.by >= 17:
                self.by = 17
            time.sleep(0.1)
        if key_pressed[pygame.K_UP]:
            self.rotate_data()
            time.sleep(0.1)

        self.check_hit()

    def draw(self, screen):
        if not self.visible:
            return

        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    pygame.draw.rect(screen, self.color,
                                     (GW.BOARD_LEFT + (self.bx + ci) * GW.BLOCK_SIZE,
                                      GW.BOARD_TOP + (self.by + li) * GW.BLOCK_SIZE,
                                      GW.BLOCK_SIZE, GW.BLOCK_SIZE))
                    screen.blit(self.image, (GW.BOARD_LEFT + (self.bx + ci) * GW.BLOCK_SIZE,
                                      GW.BOARD_TOP + (self.by + li) * GW.BLOCK_SIZE))

    def check_hit(self):
        self.check_left_border()
        self.check_right_border()
        self.check_button_border()
        self.check_board()

    def check_left_border(self):
        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    if self.bx + ci < 0:
                        self.bx += 1
                        return

    def check_right_border(self):
        for line in self.data:
            for ci, col in enumerate(line):
                if col == 1:
                    if self.bx + ci > 9:
                        self.bx -= 1
                        return

    def check_button_border(self):
        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    if self.by + li > 19:
                        self.by -= 1
                        self.change_board()
                        return

    def change_board(self):
        """固定方块"""
        for li, line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    self.board.data[self.by + li][self.bx + ci] = self.type_name

        self.new_turn()

    def new_turn(self):
        self.random_data()
        self.by = 0
        self.bx = random.randint(0, 9)

    def check_board(self):
        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    try:
                        if self.board.data[self.by + li][self.bx + ci] != 0:
                            self.by -= 1
                            self.change_board()
                            return
                    except Exception:
                        pass

    def rotate_data(self):

        # new_box = [[0 for i in range(4)] for j in range(4)]
        # for i in range(4):
        #     for j in range(3, -1, -1):
        #         new_box[i][j] = self.data[3 - j][i]
        # self.data = new_box
        new_data = [[0 for i in range(4)] for j in range(4)]
        for li, line in enumerate(self.data):
            for ci, cell in enumerate(line):
                new_data[ci][3 - li] = cell
        self.data = new_data

    def random_data(self):
        type = random.choice(BlockType.types)
        self.color = type.get("color")
        self.data = type.get("data")
        self.type_name = type.get("name")
        self.image = self.image_dict.get(self.type_name)


    def on_game_over(self, event=None):
        self.enable = False
        self.visible = False

    def on_game_pause(self, event=None):
        self.enable = False

    def on_game_resume(self, event=None):
        self.enable = True

    def check_left(self):
        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    try:
                        if self.board.data[self.by + li][self.bx + ci] != 0:
                            self.bx += 1
                            return
                    except Exception:
                        pass

    def check_right(self):
        for li,line in enumerate(self.data):
            for ci, col in enumerate(line):
                if col == 1:
                    try:
                        if self.board.data[self.by + li][self.bx + ci] != 0:
                            self.bx -= 1
                            return
                    except Exception:
                        pass

    def load_images(self):
        """
        L": "blue.png",
        "S": "red.png",
        "Z": "yellow.png",
        "J": "purple.png",
        "I": "cyan.png",
        "T": "green.png",
        "O": "red.png",
        """
        self.image_dict["L"] = \
            pygame.image.load("img/" + BlockType.images.get("L"))
        self.image_dict["S"] = \
            pygame.image.load("img/" + BlockType.images.get("S"))
        self.image_dict["Z"] = \
            pygame.image.load("img/" + BlockType.images.get("Z"))
        self.image_dict["J"] = \
            pygame.image.load("img/" + BlockType.images.get("J"))
        self.image_dict["I"] = \
            pygame.image.load("img/" + BlockType.images.get("I"))
        self.image_dict["T"] = \
            pygame.image.load("img/" + BlockType.images.get("T"))
        self.image_dict["O"] = \
            pygame.image.load("img/" + BlockType.images.get("O"))
